import { Observable, Subscription } from 'rxjs';

enum State {
    NEW,
    COMPLETING,
    NORMAL,
    EXCEPTIONAL,
    CANCELLED
}

export class Future<T> {
    private sub$: Subscription;
    // tslint:disable-next-line:variable-name
    private _value: T;
    // tslint:disable-next-line:variable-name
    private _error: any;
    // tslint:disable-next-line:variable-name
    private _state: State;

    get isCancelled() {
        return this._state === State.CANCELLED;
    }

    get isDone() {
        return this._state !== State.NEW;
    }

    get isError() {
        return this._state === State.EXCEPTIONAL;
    }

    get value() {
        return this._value;
    }

    get errorMsg() {
        return this._error
    }

    constructor(private observable: Observable<T>) {
        this._state = State.NEW;
        const self = this;
        this.sub$ = observable.subscribe({
            next(value) {
                self._value = value;
                self._state = State.COMPLETING;
                // console.log('next', value);
            },
            error(err) {
                self._error = err;
                self._state = State.EXCEPTIONAL;
                // console.log('error', err);
            },
            complete() {
                // console.log('complete');
                self._state = State.NORMAL;
            }
        });
    }

    cancel() {
        if (this._state === State.NEW) {
            this._state = State.CANCELLED;
            this.sub$.unsubscribe();
            this.sub$ = null;
        }
    }
}
